package com.macro.mall.portal.controller.pms;

import cn.hutool.core.bean.BeanUtil;
import com.github.pagehelper.Page;
import com.macro.mall.common.api.CommonPage;
import com.macro.mall.common.api.CommonResult;
import com.macro.mall.common.api.exception.BusinessException;
import com.macro.mall.common.api.util.BigDecimalUtils;
import com.macro.mall.pms.domain.*;
import com.macro.mall.pms.entity.AttributeEntity;
import com.macro.mall.pms.entity.ProductAttributeValueEntity;
import com.macro.mall.pms.entity.ProductEntity;
import com.macro.mall.pms.entity.SkuEntity;
import com.macro.mall.pms.enums.ProductPublishStatusEnum;
import com.macro.mall.pms.service.*;
import com.macro.mall.pms.service.bo.PagedQueryProductInput;
import com.macro.mall.portal.controller.BaseController;
import com.macro.mall.portal.dto.pms.PagedQueryProductReqDto;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;


/**
 * 商品信息控制器
 *
 * @author xuyanjun
 * @date 2019-12-14
 */
@Api(tags = "ProductController", description = "商品信息")
@Slf4j(topic = "ProductController")
@RestController
@RequestMapping("/product")
public class ProductController extends BaseController {

    @Autowired
    private ProductService productService;

    @Autowired
    private SkuService skuService;

    @Autowired
    private AttributeCategoryService attributeCategoryService;

    @Autowired
    private AttributeService attributeService;

    @Autowired
    private ProductAttributeValueService productAttributeValueService;

    /**
     * 分页查询商品信息
     *
     * @return 分页后的商品信息
     */
    @ApiOperation("分页查询商品信息")
    @PostMapping("pagedQuery")
    public CommonPage<Product> pagedQuery(@RequestBody PagedQueryProductReqDto reqDto) {
        PagedQueryProductInput pagedQueryProductInput = new PagedQueryProductInput();
        pagedQueryProductInput
                .setPublishStatusEnum(ProductPublishStatusEnum.UP)
                .setSortField(PagedQueryProductInput.SORT_FIELD_NAME)
                .setPageIndex(reqDto.getPageIndex())
                .setPageSize(reqDto.getPageSize());

        Page<ProductEntity> page = productService.pagedQuery(pagedQueryProductInput);

        List<Product> products = productService.entityToDomain(page);

        return CommonPage.restPage(products, page);
    }

    /**
     * 根据id获取商品信息
     *
     * @param id id
     * @return 商品信息
     */
    @ApiOperation("根据id获取商品信息")
    @GetMapping("{id}")
    public CommonResult<Product> getById(@PathVariable long id) {
        if (id <= 0) {
            throw new BusinessException("要获取的商品信息Id不能为空。");
        }

        ProductEntity productEntity = productService.getById(id);
        if (productEntity == null) {
            throw new BusinessException(String.format("要获取的商品信息id:%s不存在。", id));
        }

        Product product = productService.entityToDomain(productEntity);
        return CommonResult.success(product);
    }

    /**
     * 根据id获取商品详情(包含sku)
     *
     * @param id id
     * @return 商品信息
     */
    @ApiOperation("根据id获取商品详情(包含sku)")
    @GetMapping("detail/{id}")
    public CommonResult<ProductDetail> getDetailById(@PathVariable long id) {
        if (id <= 0) {
            throw new BusinessException("要获取的商品信息Id不能为空。");
        }

        ProductEntity productEntity = productService.getById(id);
        if (productEntity == null) {
            throw new BusinessException(String.format("要获取的商品信息id:%s不存在。", id));
        }

        Product product = productService.entityToDomain(productEntity);
        ProductDetail productDetail = productToDetail(product);

        return CommonResult.success(productDetail);
    }

    /**
     * 商品转商品详情
     *
     * @param product 商品
     * @return 商品详情
     */
    private ProductDetail productToDetail(Product product) {
        ProductDetail productDetail = new ProductDetail();

        BeanUtil.copyProperties(product, productDetail);

        List<SkuEntity> skuEntities = skuService.listByProductId(product.getId());
        List<Sku> skus = skuService.entityToDomain(skuEntities);

        List<ProductAttributeValueEntity> productAttributeValueEntities = productAttributeValueService.listByProductId(product.getId());
        List<ProductAttributeValue> productAttributeValues = productAttributeValueService.entityToDomain(productAttributeValueEntities);

        List<AttributeEntity> attributeEntities = attributeService.listByAttributeCategoryId(product.getProductAttributeCategoryId())
                .stream().filter(x -> x.getType() == 0).collect(Collectors.toList());
        List<Attribute> attributes = attributeService.entityToDomain(attributeEntities);

        List<ProductDetail.SkuTree> skuTrees = new ArrayList<>();

        for (Attribute attribute : attributes) {
            ProductDetail.SkuTree skuTree = new ProductDetail.SkuTree();
            skuTree.setSkuKeyName(attribute.getName())
                    .setSkuKeyStr(attribute.getName());

            List<String> values = new ArrayList<>();

            // 手工录入
            if (attribute.getInputType() == 0) {
                Optional<ProductAttributeValue> optionalProductAttributeValue = productAttributeValues.stream().filter(x -> x.getProductAttributeId().equals(attribute.getId())).findFirst();
                if (!optionalProductAttributeValue.isPresent()) {
                    continue;
                }
                values = optionalProductAttributeValue.get().getValues();
            }
            // 从列表中选取
            if (attribute.getInputType() == 1) {
                values = attribute.getInputList();
            }

            List<ProductDetail.SkuValue> skuValues = new ArrayList<>();
            for (String attributeValue : values) {
                String skuPic = obtainSkuImgByValue(skus, attributeValue);

                ProductDetail.SkuValue skuValue = new ProductDetail.SkuValue();
                skuValue.setId(attributeValue)
                        .setName(attributeValue)
                        .setImgUrl(skuPic)
                        .setPreviewImgUrl(skuPic);

                skuValues.add(skuValue);
            }
            skuTree.setSkuValues(skuValues);
            skuTrees.add(skuTree);
        }

        ProductDetail.Sku sku = new ProductDetail.Sku();
        sku.setSkuTrees(skuTrees);

        productDetail.setSku(sku);

        List<Map<String, Object>> productDetailskuList = new ArrayList<>();
        skus.forEach(x -> {
            Map<String, Object> map = obtainSkuMap(attributes, productAttributeValues, x);
            productDetailskuList.add(map);
        });

        sku.setList(productDetailskuList);
        sku.setHideStock(false)
                .setNoneSku(false)
                .setStockNum(product.getStock())
                .setPrice(product.getPrice());

        return productDetail;
    }

    private String obtainSkuImgByValue(List<Sku> skus, String value) {
        for (Sku sku : skus) {
            if (Objects.equals(sku.getSp1(), value)
                    || Objects.equals(sku.getSp2(), value)
                    || Objects.equals(sku.getSp3(), value)
            ) {
                return sku.getPic();
            }
        }
        return null;
    }

    private Map<String, Object> obtainSkuMap(List<Attribute> attributes, List<ProductAttributeValue> productAttributeValues, Sku sku) {
        Map<String, Object> map = new HashMap<>(8);
        map.put("id", sku.getId());
        map.put("price", BigDecimalUtils.fromYuanToFeng(sku.getPrice()));
        map.put("stock_num", sku.getStock());

        for (Attribute attribute : attributes) {
            ProductDetail.SkuTree skuTree = new ProductDetail.SkuTree();
            skuTree.setSkuKeyName(attribute.getName())
                    .setSkuKeyStr(attribute.getName());

            List<String> values = new ArrayList<>();

            // 手工录入
            if (attribute.getInputType() == 0) {
                Optional<ProductAttributeValue> optionalProductAttributeValue = productAttributeValues.stream().filter(x -> x.getProductAttributeId().equals(attribute.getId())).findFirst();
                if (!optionalProductAttributeValue.isPresent()) {
                    continue;
                }
                values = optionalProductAttributeValue.get().getValues();
            }
            // 从列表中选取
            if (attribute.getInputType() == 1) {
                values = attribute.getInputList();
            }

            if (values.contains(sku.getSp1())) {
                map.put(attribute.getName(), sku.getSp1());
                continue;
            }
            if (values.contains(sku.getSp2())) {
                map.put(attribute.getName(), sku.getSp2());
                continue;
            }
            if (values.contains(sku.getSp3())) {
                map.put(attribute.getName(), sku.getSp3());
                continue;
            }
        }

        return map;
    }

    /**
     * 根据批量id获取商品信息
     *
     * @param ids ids
     * @return 商品信息
     */
    @ApiOperation("根据批量id获取商品信息")
    @PostMapping("listByBatchIds")
    public CommonResult<List<Product>> listByBatchIds(@RequestBody List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            throw new BusinessException("要获取的商品信息Id集合不能为空。");
        }

        List<ProductEntity> productEntities = productService.listByBatchIds(ids);

        List<Product> products = productService.entityToDomain(productEntities);
        return CommonResult.success(products);
    }

}

